home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume18 / ofiles.new < prev    next >
Encoding:
Text File  |  1989-10-15  |  36.0 KB  |  1,543 lines

  1. Article 316 of comp.sources.unix:
  2. Path: mentor.cc.purdue.edu!purdue!mailrus!tut.cis.ohio-state.edu!bloom-beacon!apple!bbn!bbn.com!rsalz
  3. From: rsalz@uunet.uu.net (Rich Salz)
  4. Newsgroups: comp.sources.unix
  5. Subject: v18i057:  REVISED ofiles, doesn't need Sun source
  6. Message-ID: <1611@fig.bbn.com>
  7. Date: 24 Mar 89 17:43:04 GMT
  8. Lines: 1530
  9. Approved: rsalz@uunet.UU.NET
  10.  
  11. Submitted-by: abe@mace.cc.purdue.edu (Vic Abell)
  12. Posting-number: Volume 18, Issue 57
  13. Archive-name: ofiles.new
  14.  
  15. Here's a new shar of ofiles.  When I saw how little ofiles needed
  16. from /usr/src/sys/specfs/snode.h, I decided to define it in ofiles.c.
  17. This version should now compile for folks who do not have Sun sources.
  18.  
  19. Sorry for the problem.  I'm just about done with fstat, and I have
  20. made sure it doesn't have the same difficulty.
  21.  
  22. Vic Abell
  23.  
  24. #    This is a shell archive.
  25. #    Remove everything above and including the cut line.
  26. #    Then run the rest of the file through sh.
  27. #----cut here-----cut here-----cut here-----cut here----#
  28. #!/bin/sh
  29. # shar:    Shell Archiver
  30. #    Run the following text with /bin/sh to create:
  31. #    README
  32. #    Makefile
  33. #    ofiles.c
  34. #    ofiles.8l
  35. # This archive created: Thu Mar 23 19:42:54 1989
  36. # By:    Vic Abell (Purdue University)
  37. echo shar: extracting README '(1315 characters)'
  38. sed 's/^XX//' << \SHAR_EOF > README
  39. XXOfiles shows the owner of an open file or network connection.
  40. XX
  41. XXC. Spencer is the original author of ofiles.  Michael Ditto, Tom Dunigan,
  42. XXAlexander Dupuy, Gary Nebbett and Richard Tobin made contributions.  Mike
  43. XXSpitzer, Ray Moody and Vik Lall of the Purdue University Computing Center
  44. XX(PUCC) adapted ofiles to a number of different UNIX environments.  I added
  45. XXthe network connection option.
  46. XX
  47. XXOfiles compiles and runs on 4.3BSD, DYNIX 3.0.12 (Balance) and 3.0.14
  48. XX(Symmetry), SunOS 4.0 and ULTRIX 2.2.  It is free of lint on those systems
  49. XXaccording to the lint libraries in use at PUCC.
  50. XX
  51. XXSpecial notes:
  52. XX
  53. XX    1.  A "generic" Makefile is included.  You may have to adjust it
  54. XX        to your local conditions.
  55. XX
  56. XX    2.  SunOS 4.0 loading requires "-lkvm", so modify the Makefile
  57. XX        accordingly when you port ofiles to your Sun system.
  58. XX
  59. XX    3.  Ofiles needs permission to read /dev/drum (swap files), /dev/kmem
  60. XX        and /dev/mem.  PUCC uses a "setgid kmem" approach - i. e.,
  61. XX        /dev/{drum,kmem,mem} are in the kmem group and ofiles has mode
  62. XX        2755, group kmem.  The Makefile install rule implements this
  63. XX        convention.
  64. XX
  65. XXThe ofiles distribution includes:
  66. XX
  67. XX    README        this file
  68. XX    Makefile    a generic Makefile
  69. XX    ofiles.c    source
  70. XX    ofiles.8l    man page
  71. XX
  72. XXVic Abell, abe@mace.cc.purdue.edu
  73. XXPurdue University Computing Center
  74. XXMarch 22, 1989
  75. SHAR_EOF
  76. if test 1315 -ne "`wc -c README`"
  77. then
  78. echo shar: error transmitting README '(should have been 1315 characters)'
  79. fi
  80. echo shar: extracting Makefile '(738 characters)'
  81. sed 's/^XX//' << \SHAR_EOF > Makefile
  82. XX#
  83. XX#    Makefile for ofiles
  84. XX#
  85. XX
  86. XXPROG=    ofiles
  87. XXBIN=    ${DESTDIR}/usr/local/etc
  88. XX
  89. XXI=/usr/include
  90. XXS=/usr/include/sys
  91. XXL=/usr/include/local
  92. XX
  93. XXINCLUDE=
  94. XXDEBUG=    -O
  95. XXCDEFS=  
  96. XXCFLAGS= ${DEBUG} ${CDEFS} ${INCLUDE}
  97. XX
  98. XXHDR=    
  99. XXONEC=    ofiles.c
  100. XXOTHER=    
  101. XXSOURCE=    Makefile ${HDR} ${ONEC} ${OTHER}
  102. XX
  103. XXall: ${PROG}
  104. XX
  105. XX# SunOS 4.0 needs -lkvm in the following rule
  106. XX
  107. XX${PROG}:
  108. XX    ${CC} -o $@ ${CFLAGS} ${ONEC} 
  109. XX
  110. XXclean: FRC
  111. XX    rm -f Makefile.bak ${PROG} *.o a.out core errs tags
  112. XX
  113. XXinstall: all FRC
  114. XX    install -cs -m 2755 -g kmem ${PROG} ${BIN}
  115. XX
  116. XXlint: ${HDR} ${ONEC} FRC
  117. XX    lint ${CDEFS} ${INCLUDE} ${ONEC}
  118. XX
  119. XXprint: source FRC
  120. XX    lpr -J'${PROG} source' ${SOURCE}
  121. XX
  122. XXsource: ${SOURCE}
  123. XX
  124. XXspotless: clean
  125. XX    rcsclean ${SOURCE}
  126. XX
  127. XXtags: ${HDR} ${ONEC}
  128. XX    ctags -t ${HDR} ${ONEC}
  129. XX
  130. XX${SOURCE}:
  131. XX    co -q $@
  132. XX
  133. XXFRC:
  134. XX
  135. SHAR_EOF
  136. if test 738 -ne "`wc -c Makefile`"
  137. then
  138. echo shar: error transmitting Makefile '(should have been 738 characters)'
  139. fi
  140. echo shar: extracting ofiles.c '(24522 characters)'
  141. sed 's/^XX//' << \SHAR_EOF > ofiles.c
  142. XX/*    ofiles.c
  143. XX *
  144. XX *    ofiles [-d ] [-k nlist core] [-n] [-p] args
  145. XX *
  146. XX *    Show owner of open file or network connection.
  147. XX *
  148. XX *    Reports owner, process ID, access type, command and inode number.
  149. XX *
  150. XX *    -d        select verbose debugging output
  151. XX *
  152. XX *    -k nlist core    specifies alternative name list and core files
  153. XX *            (DYNIX only)
  154. XX *
  155. XX *    -n        interpret names as network connection, hexadecimal
  156. XX *            Protocol Control Block (PCB) addresses
  157. XX *
  158. XX *    -p          gives brief (pids only) report
  159. XX *
  160. XX *    names        file names, file system names or network connection
  161. XX *            PCB addresses
  162. XX *
  163. XX *    Stat each file or file system argument and scan the process table,
  164. XX *    looking for a match in the associated user structure's file lists.
  165. XX *
  166. XX *    Follow each PCB arg to the Internet Protocol Control Block (INPCB),
  167. XX *    thence to the socket; then scan the file table to find the file
  168. XX *    structure address associated with the socket; finally, scan the
  169. XX *    process table, looking for a nacth in the associated user structure's
  170. XX *    file lists.
  171. XX *
  172. XX *    Doesn't handlle remote NFS files.
  173. XX */
  174. XX
  175. XX/*
  176. XX *    Authors:
  177. XX *
  178. XX *    The orignal author is:
  179. XX *
  180. XX *        C. Spencer
  181. XX *
  182. XX *    Contributors include:
  183. XX *
  184. XX *        Michael Ditto
  185. XX *        Tom Dunigan
  186. XX *        Alexander Dupuy
  187. XX *        Greg Nebbett
  188. XX *        Richard Tobin
  189. XX *
  190. XX *    From the Purdue University Computing Center:
  191. XX *
  192. XX *        Mike Spitzer         converted to 4.3BSD, DYNIX 3.0.1[24]
  193. XX *        Ray Moody        SunOS 4.0 and ULTRIX 2.2
  194. XX *        Vik Lall
  195. XX *
  196. XX *        Vic Abell        added socket option and removed lint
  197. XX *                
  198. XX */
  199. XX
  200. XX#ifndef lint
  201. XXstatic char rcsid[]="$Header: /usr/src/local/etc/ofiles/RCS/ofiles.c,v 1.8 89/03/21 12:29:30 abe Exp Locker: abe $";
  202. XX#endif /* lint */
  203. XX
  204. XX#include <sys/param.h>
  205. XX#include <sys/dir.h>
  206. XX#include <sys/user.h>
  207. XX
  208. XX#ifdef DYNIX
  209. XX#define KERNEL
  210. XX#include <sys/file.h>
  211. XX#include <sys/vnode.h>
  212. XX#include <sys/inode.h>
  213. XX#undef KERNEL
  214. XX#else
  215. XX#define KERNEL
  216. XX#include <sys/file.h>
  217. XX#ifndef sun
  218. XX#include <sys/inode.h>
  219. XX#endif
  220. XX#undef KERNEL
  221. XX#endif
  222. XX
  223. XX#include <machine/pte.h>
  224. XX#if !defined(ultrix) && !defined(sun)
  225. XX#include <machine/machparam.h>
  226. XX#endif
  227. XX#include <sys/proc.h>
  228. XX#include <nlist.h>
  229. XX#include <sys/stat.h>
  230. XX#include <pwd.h>
  231. XX#include <fstab.h>
  232. XX#include <sys/vmmac.h>
  233. XX#include <stdio.h>
  234. XX
  235. XX#ifdef sun
  236. XX#include <sys/vnode.h>
  237. XX#include <ufs/inode.h>
  238. XX#include <kvm.h>
  239. XXstruct snode {
  240. XX    struct snode *s_next;
  241. XX    struct vnode s_vnode;
  242. XX    struct vnode *s_realvp;
  243. XX    struct vnode *s_bdevvp;
  244. XX    u_short s_flag;
  245. XX    dev_t s_dev;
  246. XX};
  247. XXkvm_t    *kd;
  248. XX#endif
  249. XX
  250. XX#ifdef ultrix
  251. XX#include <sys/gnode.h>
  252. XX#include <sys/gnode_common.h>
  253. XX#include <machine/param.h>
  254. XX#endif
  255. XX
  256. XX#include <sys/socket.h>
  257. XX#include <sys/socketvar.h>
  258. XX#include <net/route.h>
  259. XX#include <netinet/in.h>
  260. XX#include <netinet/in_pcb.h>
  261. XX#include <netinet/tcp.h>
  262. XX#include <netinet/tcp_fsm.h>
  263. XX#include <netinet/tcp_timer.h>
  264. XX#include <netinet/tcp_var.h>
  265. XX
  266. XX#define CDIR    01
  267. XX#define OFILE    02
  268. XX#define RDIR    04
  269. XX#define SHFILE    010
  270. XX#define EXFILE    020
  271. XX#define SOCKET  040
  272. XX
  273. XXchar *namelist;
  274. XXchar *corefile;
  275. XXint k_opt = 0;
  276. XXint n_opt = 0;
  277. XX
  278. XX#ifdef    ultrix
  279. XX#define    ls_t    long
  280. XX#else
  281. XX#define ls_t    off_t
  282. XX#endif
  283. XX
  284. XX#ifdef    sun
  285. XXchar    *sprintf();
  286. XX#endif
  287. XX
  288. XXls_t lseek(), vtophys();
  289. XX
  290. XXvoid eread(), eseek();
  291. XX#ifdef    ultrix
  292. XXvoid exit(), nlist(), perror();
  293. XX#endif
  294. XX
  295. XXint nproc;        /* number of entries in proc table         */
  296. XXint mem;        /* fd for /dev/mem                */
  297. XXint kmem;
  298. XXint swap;        /* fd for /dev/swap                */
  299. XXlong procbase;
  300. XXint ppid = -1;        /* previously display PID */
  301. XX
  302. XXint dirinode;        /* directory (CDIR or RDIR) inode */
  303. XXint opninode;        /* save inode of open file */
  304. XXint pids_only = 0;    /* if non-zero, only output process ids    */
  305. XX
  306. XXchar *progname;
  307. XXstruct nlist nl[] = {
  308. XX#define    X_PROC        0
  309. XX    { "_proc" },
  310. XX#define X_NPROC     1
  311. XX    {"_nproc"},
  312. XX#define X_USRPTMA    2
  313. XX        {"_Usrptmap"},    
  314. XX#define X_USRPT        3
  315. XX    {"_usrpt"},
  316. XX#define X_SYSMAP    4
  317. XX    {"_Sysmap"},
  318. XX#define    SFIL        5
  319. XX    { "_file" },
  320. XX#define    SNFILE        6
  321. XX    { "_nfile" },
  322. XX    { "" },
  323. XX};
  324. XX
  325. XX#ifndef    DYNIX
  326. XXstruct pte *usrpt, *Usrptma;
  327. XX#endif
  328. XX
  329. XXint debug;
  330. XX
  331. XXmain(argc, argv)
  332. XX    int     argc;
  333. XX    char    *argv[];
  334. XX{
  335. XX
  336. XX#ifdef ultrix
  337. XX    struct gnode *i, *getinode();
  338. XX#else
  339. XX    struct inode *i, *getinode();
  340. XX#endif
  341. XX    struct stat s;
  342. XX    struct user *u, *getuser();
  343. XX    struct proc p;
  344. XX    register int filen, flags, procn;
  345. XX    register char *filename, *fsname;
  346. XX    struct fstab *fs, *getfsfile(), *getfsspec();
  347. XX    char *getsockfp(), *rindex();
  348. XX    struct file *fp;
  349. XX    int ax, err, findf, nmct;
  350. XX    char *ap;
  351. XX    int exitval = 0;
  352. XX
  353. XX#ifdef    lint
  354. XX/*
  355. XX * The following code satisfies lint for KERNEL symbols.
  356. XX * This program is lint-free under 4.3BSD, DYNIX 3.0.1[24], SunOS 4.0
  357. XX * and ULTRIX 2.2, using the lint libraries of the systems at the
  358. XX * Purdue University Computing Center.
  359. XX */
  360. XX#if    !defined(ultrix) && !defined(DYNIX) && !defined(sun)
  361. XX    long lintlong;
  362. XX#endif
  363. XX#ifdef    ultrix
  364. XX    struct nch *lintnch;
  365. XX    float lintfloat;
  366. XX#endif
  367. XX#if    !defined(DYNIX)
  368. XX    file = fileNFILE = NULL;
  369. XX    fp = file;
  370. XX    fp = fileNFILE;
  371. XX    nfile = 0;
  372. XX    filen = nfile;
  373. XX#endif
  374. XX#if    !defined(ultrix) && !defined(DYNIX) && !defined(sun)
  375. XX    inode = inodeNINODE = rootdir = NULL;
  376. XX    i = inode;
  377. XX    i = inodeNINODE;
  378. XX    i = rootdir;
  379. XX    ninode = 0;
  380. XX    nextinodeid = 0l;
  381. XX    lintlong = nextinodeid;
  382. XX    nextinodeid = lintlong;
  383. XX    filen = ninode;
  384. XX#endif
  385. XX#ifdef    sun
  386. XX    tcp_ttl = 0;
  387. XX    filen  = tcp_ttl;
  388. XX#endif
  389. XX#ifdef    ultrix
  390. XX    nch = NULL;
  391. XX    lintnch = nch;
  392. XX    nch = lintnch;
  393. XX    nchsize = 0;
  394. XX    filen = nchsize;
  395. XX    tcp_alpha = tcp_beta = 0.0;
  396. XX    lintfloat = tcp_alpha;
  397. XX    lintfloat = tcp_beta;
  398. XX    tcp_alpha = lintfloat;
  399. XX#endif
  400. XX#endif    /* lint */
  401. XX
  402. XX    if ((progname = rindex(argv[0], '/')))
  403. XX        progname++;
  404. XX    else
  405. XX        progname = argv[0];
  406. XX
  407. XX    if (argc == 1) {
  408. XX
  409. XXusage:
  410. XX
  411. XX#ifdef    DYNIX
  412. XX        (void) fprintf(stderr,
  413. XX            "usage: %s [-d ] [-k nlist core] [-n] [-p] names\n",
  414. XX            progname);
  415. XX#else
  416. XX        (void) fprintf(stderr,
  417. XX            "usage: %s [-d ] [-n] [-p] names\n", progname);
  418. XX#endif
  419. XX        (void) fprintf(stderr, "\t-d    = select verbose debugging output\n");
  420. XX#ifdef    DYNIX
  421. XX        (void) fprintf(stderr,
  422. XX            "\t-k    = use specified nlist and core files\n");
  423. XX#endif
  424. XX        (void) fprintf(stderr,
  425. XX            "\t-n    = interpret names as network connection, hexadecimal,\n");
  426. XX        (void) fprintf(stderr,
  427. XX            "\t        Protocol Control Block (PCB) addresses, as supplied\n");
  428. XX        (void) fprintf(stderr,
  429. XX            "\t        by netstat's -A option\n");
  430. XX        (void) fprintf(stderr, "\t-p    = print only process IDs\n");
  431. XX        (void) fprintf(stderr,
  432. XX            "\tnames = file names or PCB addresses\n");
  433. XX        exit(exitval);
  434. XX    }
  435. XX
  436. XX    /* check for switches */
  437. XX    for (err = 0, ax = 1; ax < argc; ax++) {
  438. XX        ap = argv[ax];
  439. XX        if (*ap++ != '-')
  440. XX            break;
  441. XX        while (*ap) {
  442. XX            switch (*ap++) {
  443. XX
  444. XX            case 'd':
  445. XX                debug = 1;
  446. XX                break;
  447. XX#ifdef    DYNIX
  448. XX            case 'k':
  449. XX                if ((ax + 2) >= argc) {
  450. XX                    (void) fprintf(stderr,
  451. XX                        "%s: no nlist/core after -k\n",
  452. XX                        progname);
  453. XX                    err++;
  454. XX                } else {
  455. XX                    namelist = argv[++ax];
  456. XX                    corefile = argv[++ax];
  457. XX                    k_opt = 1;
  458. XX                    continue;
  459. XX                }
  460. XX                break;
  461. XX#endif
  462. XX            case 'n':
  463. XX                n_opt++;
  464. XX                break;
  465. XX
  466. XX            case 'p':
  467. XX                pids_only = 1;
  468. XX                break;
  469. XX
  470. XX            default:
  471. XX                (void) fprintf(stderr,
  472. XX                    "%s: unknown switch - %c\n",
  473. XX                    progname, *(ap - 1));
  474. XX                err++;
  475. XX            }
  476. XX        }
  477. XX    }
  478. XX    if (ax >= argc) {
  479. XX        (void) fprintf(stderr, "%s: no names specified\n", progname);
  480. XX        err++;
  481. XX    }
  482. XX    if (err) {
  483. XX        exitval = 1;
  484. XX        goto usage;
  485. XX    }
  486. XX
  487. XX#ifdef sun
  488. XX        if ((kd = kvm_open (NULL, NULL, NULL, O_RDONLY)) == 0) {
  489. XX        (void) fprintf(stderr, "%s: can't access memory: ",
  490. XX            progname);
  491. XX            perror ("");
  492. XX        exit(1);
  493. XX    }
  494. XX#endif
  495. XX    if ((mem = open("/dev/mem", 0)) < 0) {
  496. XX        (void) fprintf(stderr, "%s: /dev/mem: ", progname);
  497. XX        perror("");
  498. XX        exit(1);
  499. XX    }
  500. XX    if (k_opt) {
  501. XX        if ((kmem = open(corefile, 0)) < 0) {
  502. XX            (void) fprintf(stderr, "%s: %s: ",
  503. XX                progname, corefile);
  504. XX            perror("");
  505. XX            exit(1);
  506. XX        }
  507. XX    } else {
  508. XX        if ((kmem = open("/dev/kmem", 0)) < 0) {
  509. XX            (void) fprintf(stderr, "%s: /dev/kmem: ", progname);
  510. XX            perror("");
  511. XX            exit(1);
  512. XX        }
  513. XX    }
  514. XX    if (!k_opt) 
  515. XX        if ((swap = open("/dev/drum", 0)) < 0) {
  516. XX            (void) fprintf(stderr, "%s: /dev/drum: ", progname);
  517. XX            perror("");
  518. XX            exit(1);
  519. XX        }
  520. XX
  521. XX    getsyms();
  522. XX
  523. XX    for (err = 0, nmct = argc - ax; ax < argc; ax++) {
  524. XX        /* if -n, then arg is a PCB */
  525. XX        if (n_opt) {
  526. XX            if ((filename = getsockfp(argv[ax], &fp)) == NULL) {
  527. XX                err++;
  528. XX                continue;
  529. XX            }
  530. XX            fsname = "";
  531. XX        } else {
  532. XX            /* assume arg is  a filesystem */
  533. XX            if ((fs = getfsfile(argv[ax])) != NULL) {
  534. XX                fsname = argv[ax];
  535. XX                if (strcmp(".", argv[ax]) == 0)
  536. XX                    filename = argv[ax];
  537. XX                else
  538. XX                    filename = fs->fs_spec;
  539. XX            /* maybe it's the device name for a filesystem */
  540. XX            } else if ((fs = getfsspec(argv[ax])) != NULL) {
  541. XX                filename = argv[ax];
  542. XX                fsname = fs->fs_file;
  543. XX            /* probably a regular file */
  544. XX            } else {
  545. XX                filename = argv[ax];
  546. XX                fsname = "";
  547. XX            }
  548. XX            if (stat(filename, &s)) {
  549. XX                (void) fprintf(stderr, "%s: can't stat %s: ",
  550. XX                    progname, filename);
  551. XX                perror("");
  552. XX                err++;
  553. XX                continue;
  554. XX            }
  555. XX            if (debug)
  556. XX                (void) printf(
  557. XX                    "stat dev %x ino %d mode %x rdev %x\n",
  558. XX                    s.st_dev, s.st_ino, s.st_mode,
  559. XX                    s.st_rdev);
  560. XX        }
  561. XX        if (! pids_only) {
  562. XX            (void) printf("%s\t%s", filename, fsname);
  563. XX            if (!n_opt) {
  564. XX                if ((s.st_mode & S_IFMT) == S_IFDIR)
  565. XX                    (void) printf("(directory)");
  566. XX            }
  567. XX            (void) printf("\n%-8.8s  %5s  %-6.6s  FD  %-14.14s",
  568. XX                "USER", "PID", "TYPE", "CMD");
  569. XX            if (!n_opt)
  570. XX                (void) printf("  INODE");
  571. XX            (void) printf("\n");
  572. XX        }
  573. XX        for (findf = procn = 0; procn < nproc; procn++) {
  574. XX            procslot(procn, &p);
  575. XX            flags = 0;
  576. XX            if (p.p_stat == 0 || p.p_stat == SZOMB) 
  577. XX                continue;
  578. XX#ifdef sun
  579. XX                u = kvm_getu(kd, &p);
  580. XX#else
  581. XX            u = getuser(&p);
  582. XX#endif
  583. XX
  584. XX            if ( u == (struct user *)NULL)
  585. XX                continue;
  586. XX            if (debug)
  587. XX                (void) printf("pid %d uid %d cmd %s\n", p.p_pid,
  588. XX                    p.p_uid, u->u_comm);
  589. XX            if (!n_opt) {
  590. XX                i = getinode(u->u_rdir, "rdir");
  591. XX                if (check(&s, i)) {
  592. XX                    dirinode = s.st_ino;
  593. XX                    gotone(u, &p, -1, RDIR);
  594. XX                    findf++;
  595. XX                }
  596. XX                i = getinode(u->u_cdir, "cdir");
  597. XX                if (check(&s, i)) {
  598. XX                    dirinode = s.st_ino;
  599. XX                    gotone(u, &p, -1, CDIR);
  600. XX                    findf++;
  601. XX                }
  602. XX            }
  603. XX#ifdef    DYNIX
  604. XX            for (filen = 0; filen < u->u_nofile; filen++)
  605. XX#else
  606. XX            for (filen = 0; filen < NOFILE; filen++)
  607. XX#endif    
  608. XX            {
  609. XX                struct file f;
  610. XX
  611. XX                flags = 0;
  612. XX                if (n_opt) {
  613. XX#ifdef    DYNIX
  614. XX                    if (u->u_lofile[filen].of_file != fp)
  615. XX#else
  616. XX                    if (u->u_ofile[filen] != fp)
  617. XX#endif
  618. XX                        continue;
  619. XX                } else {
  620. XX#ifdef    DYNIX
  621. XX                    if (u->u_lofile[filen].of_file == NULL)
  622. XX                        continue;
  623. XX#else
  624. XX                    if (u->u_ofile[filen] == NULL)
  625. XX                        continue;
  626. XX#endif
  627. XX                }
  628. XX
  629. XX                if (k_opt)
  630. XX#ifdef    DYNIX
  631. XX                    eseek(kmem, vtophys((ls_t)u->u_lofile[filen].of_file), 0, "file");
  632. XX#else
  633. XX                eseek(kmem, vtophys((ls_t)u->u_ofile[filen]), 0, "file");
  634. XX#endif 
  635. XX                else
  636. XX#ifdef    DYNIX
  637. XX                    eseek(kmem, (ls_t)u->u_lofile[filen].of_file, 0, "file");
  638. XX#else
  639. XX                eseek(kmem, (ls_t)u->u_ofile[filen], 0, "file");
  640. XX#endif
  641. XX                eread(kmem, (char *)&f, sizeof(f), "file");
  642. XX
  643. XX                if (f.f_count > 0) {
  644. XX                    if (n_opt && f.f_type == DTYPE_SOCKET) {
  645. XX                        gotone(u, &p, filen, SOCKET);
  646. XX                        findf++;
  647. XX                        continue;
  648. XX                    }
  649. XX#if    defined(DYNIX) || defined(sun)
  650. XX                    if (f.f_type != DTYPE_VNODE)
  651. XX#else
  652. XX                    if (f.f_type != DTYPE_INODE)
  653. XX#endif
  654. XX                        continue;
  655. XX#if    defined(DYNIX) || defined(sun)
  656. XX                    i = getinode((struct vnode *)f.f_data,
  657. XX                        "ofile");
  658. XX#else
  659. XX#ifdef    ultrix
  660. XX                    i = getinode((struct gnode *)f.f_data,
  661. XX                        "ofile");
  662. XX#else
  663. XX                    i = getinode((struct inode *)f.f_data,
  664. XX                        "ofile");
  665. XX#endif
  666. XX#endif
  667. XX                    if (check(&s, i)) {
  668. XX#if !defined(ultrix)
  669. XX                        opninode = i->i_number;
  670. XX#else
  671. XX                        opninode = (int)i->g_req.gr_number;
  672. XX#endif
  673. XX                        flags |= OFILE;
  674. XX                        if (f.f_flag & FEXLOCK) {
  675. XX                            flags |= EXFILE;
  676. XX                        }
  677. XX                        if (f.f_flag & FSHLOCK) {
  678. XX                            flags |= SHFILE;
  679. XX                        }
  680. XX                        gotone(u, &p, filen, flags);
  681. XX                        findf++;
  682. XX                    }
  683. XX                }
  684. XX            }
  685. XX        }
  686. XX        if (findf)
  687. XX            nmct--;
  688. XX        if (! pids_only) {
  689. XX                (void) printf("\n");
  690. XX            (void) fflush(stdout);
  691. XX        }
  692. XX    }
  693. XX    if (pids_only && ppid != -1) {
  694. XX        (void) printf("\n");
  695. XX        (void) fflush(stdout);
  696. XX    }
  697. XX    exitval = (err || nmct) ? 1 : 0;
  698. XX    exit(exitval);
  699. XX}        
  700. XX
  701. XX/*
  702. XX * print the name of the user owning process "p" and the pid of that process
  703. XX */
  704. XXgotone(u, p, fd, f)
  705. XX    struct user *u;
  706. XX    struct proc *p;
  707. XX    int fd;
  708. XX    int f;
  709. XX{
  710. XX    char *ty, tybuf[8], *strcat(), *strcpy();
  711. XX    struct passwd *getpwuid();
  712. XX    register struct passwd *pw;
  713. XX
  714. XX    /* only print pids and return */
  715. XX    if (pids_only) {
  716. XX        if (ppid != p->p_pid) {
  717. XX            if (ppid != -1)
  718. XX                (void) printf(" ");
  719. XX            (void) printf("%d", p->p_pid);
  720. XX            (void) fflush(stdout);
  721. XX            ppid = p->p_pid;
  722. XX        }
  723. XX        return;
  724. XX    }
  725. XX    pw = getpwuid((int)p->p_uid);
  726. XX    if (pw)
  727. XX        (void) printf("%-8.8s  ", pw->pw_name );
  728. XX    else
  729. XX        (void) printf("%-8d  ", p->p_uid);
  730. XX    (void) printf("%5d  ", p->p_pid);
  731. XX    if (f & OFILE) {
  732. XX        (void) strcpy(tybuf, "file");
  733. XX        ty = tybuf;
  734. XX        if (f & SHFILE)
  735. XX            (void) strcat(ty, "/s");
  736. XX        else if (f & EXFILE)
  737. XX            (void) strcat(ty, "/x");
  738. XX    } else if (f & CDIR)
  739. XX        ty = "cwd";
  740. XX    else if (f & RDIR)
  741. XX        ty = "rdir";
  742. XX    else if (f & SOCKET)
  743. XX        ty = "sock";
  744. XX    else
  745. XX        ty = "";
  746. XX    (void) printf("%-6.6s  ", ty);
  747. XX    if (fd >= 0)
  748. XX        (void) printf("%2d  ", fd);
  749. XX    else
  750. XX        (void) printf("    ");
  751. XX    (void) printf("%-14.14s", u->u_comm);
  752. XX    if (f & OFILE)
  753. XX        (void) printf("  %5d", opninode);
  754. XX    else if (f & (CDIR|RDIR))
  755. XX        (void) printf("  %5d", dirinode);
  756. XX    (void) printf("\n");
  757. XX    return;
  758. XX}
  759. XX
  760. XX/*
  761. XX * is inode "i" on device "s"? returns TRUE or FALSE 
  762. XX */
  763. XXcheck(s, i)
  764. XX    struct stat *s;
  765. XX#ifdef ultrix
  766. XX    struct gnode *i;
  767. XX#else
  768. XX    struct inode *i;
  769. XX#endif
  770. XX{
  771. XX    if (s == (struct stat *)NULL)
  772. XX        return 0;
  773. XX#ifdef ultrix
  774. XX    if (i == (struct gnode *)NULL)
  775. XX        return 0;
  776. XX    if ((s->st_mode & S_IFMT) == S_IFBLK && s->st_rdev == i->g_dev)
  777. XX            return 1;
  778. XX    else if ((s->st_dev == i->g_dev) && (s->st_ino == i->g_req.gr_number))
  779. XX            return 1;
  780. XX#else
  781. XX    if (i == (struct inode *)NULL) return 0;
  782. XX    if ((s->st_mode & S_IFMT) == S_IFBLK && s->st_rdev == i->i_dev)
  783. XX            return 1;
  784. XX    else if ((s->st_dev == i->i_dev) && (s->st_ino == i->i_number))
  785. XX            return 1;
  786. XX#endif
  787. XX#ifdef sun
  788. XX    else if (s->st_rdev == i->i_dev && i->i_number == 0)
  789. XX            return 1;
  790. XX#endif
  791. XX    else return 0;
  792. XX}
  793. XX
  794. XX
  795. XX/* 
  796. XX *    getinode - read an inode from from mem at address "addr"
  797. XX *           return pointer to inode struct. 
  798. XX */
  799. XX#if defined(DYNIX) || defined(sun)
  800. XXstruct inode *
  801. XXgetinode(ip, s)
  802. XX    struct vnode *ip;
  803. XX    char *s;
  804. XX{
  805. XX    static struct inode i;
  806. XX    static struct vnode v;
  807. XX#ifdef    sun
  808. XX    struct snode sn;
  809. XX#endif
  810. XX
  811. XX    if (ip == NULL)
  812. XX        return(NULL);
  813. XX    if (k_opt)
  814. XX        eseek(kmem, vtophys((ls_t)ip), 0, "vnode");
  815. XX    else
  816. XX        eseek(kmem, (ls_t)ip, 0, "vnode");
  817. XX    eread(kmem, (char *)&v, sizeof(v), "vnode");
  818. XX    if (debug)
  819. XX        (void) printf("vnode %s at %x %x dev=%x vtype=%d inode@%x\n",
  820. XX             s, ip, v.v_flag, v.v_rdev, v.v_type, v.v_data);
  821. XX    if (k_opt)
  822. XX        eseek(kmem, vtophys((ls_t)v.v_data), 0, "inode");
  823. XX    else
  824. XX        eseek(kmem, (ls_t)v.v_data, 0, "inode");
  825. XX#ifdef    sun
  826. XX    if (v.v_type == VBLK || v.v_type == VCHR || v.v_type == VFIFO) {
  827. XX        eread(kmem, (char *)&sn, sizeof(sn), "snode");
  828. XX        if (debug)
  829. XX            (void) printf(
  830. XX                "snode %s at %x %x dev=%x realvp=%x bdevvp=%x\n",
  831. XX                s, ip, sn.s_vnode.v_type, sn.s_dev,
  832. XX                sn.s_realvp, sn.s_bdevvp);
  833. XX        if (sn.s_realvp || sn.s_bdevvp) {
  834. XX            eseek(kmem,
  835. XX                (sn.s_realvp) ? (ls_t)sn.s_realvp
  836. XX                          : (ls_t)sn.s_bdevvp,
  837. XX                0, "rvnode");
  838. XX            eread(kmem, (char *)&v, sizeof(v), "rvnode");
  839. XX            eseek(kmem, (ls_t)v.v_data, 0, "rinode");
  840. XX        }
  841. XX    }
  842. XX#endif
  843. XX    eread(kmem, (char *)&i, sizeof(i), "inode");
  844. XX    if (debug)
  845. XX        (void) printf("inode %s at %x %x dev=%x inode=%d vtype=%x\n",
  846. XX            s, v.v_data, i.i_flag, i.i_dev, i.i_number,
  847. XX            i.i_vnode.v_type);
  848. XX    return &i;
  849. XX}
  850. XX
  851. XX#else
  852. XX/* ARGSUSED */
  853. XX
  854. XX#ifdef ultrix
  855. XXstruct gnode *
  856. XXgetinode(ip, s)
  857. XX    struct gnode *ip;
  858. XX#else
  859. XX
  860. XXstruct inode *
  861. XXgetinode(ip, s)
  862. XX    struct inode *ip;
  863. XX#endif
  864. XX
  865. XX    char *s;
  866. XX{
  867. XX#if defined(ultrix) 
  868. XX    static struct gnode i;
  869. XX#else
  870. XX    static struct inode i;
  871. XX#endif
  872. XX
  873. XX    eseek(kmem, (ls_t)ip, 0, "inode");
  874. XX    eread(kmem, (char *)&i, sizeof(i), "inode");
  875. XX    return &i;
  876. XX}
  877. XX#endif
  878. XX
  879. XX#if !defined(sun)
  880. XX/* 
  881. XX * get user page for proc "p" from core or swap
  882. XX * return pointer to user struct
  883. XX */
  884. XX#ifdef    DYNIX
  885. XXstruct user *
  886. XXgetuser(p)
  887. XX    struct proc *p;
  888. XX{
  889. XX    int btr;
  890. XX    ls_t sp;
  891. XX    static struct user *u = NULL;
  892. XX    char *valloc();
  893. XX
  894. XX    if (u == NULL) {
  895. XX        if ((u = (struct user *) valloc(ctob(UPAGES))) == NULL) {
  896. XX            (void) fprintf(stderr,
  897. XX                "%s: can't allocate space for user structure\n",                progname);
  898. XX            exit(1);
  899. XX        }
  900. XX    }
  901. XX    btr = ctob(UPAGES);
  902. XX    if ((p->p_flag & SLOAD) == 0) {
  903. XX        if (k_opt)
  904. XX            return (struct user *)NULL;
  905. XX        sp = (ls_t) dtob(p->p_swaddr);
  906. XX        if (lseek(swap, sp, 0) != sp) {
  907. XX            if (debug) {
  908. XX                (void) fprintf(stderr,
  909. XX                    "%s: error seeking to swap for %d: ",
  910. XX                    progname, p->p_pid);
  911. XX                perror("");
  912. XX            }
  913. XX            return (struct user *)NULL;
  914. XX        }
  915. XX        if (read(swap, (char*)u, btr) != btr) {
  916. XX            if (debug) {
  917. XX                (void) fprintf(stderr,
  918. XX                    "%s: error reading swap for %d: ",
  919. XX                    progname, p->p_pid);
  920. XX                perror("");
  921. XX            }
  922. XX            return (struct user *)NULL;
  923. XX        }
  924. XX        if (debug)
  925. XX            (void) printf("read swap\n");
  926. XX    } else {
  927. XX        if (k_opt)
  928. XX            (void) lseek(kmem, vtophys((ls_t)p->p_uarea), L_SET);
  929. XX        else
  930. XX            (void) lseek(kmem, (ls_t)p->p_uarea, L_SET);
  931. XX        if (read(kmem, (char *)u, btr) != btr)
  932. XX            return (struct user *)NULL;
  933. XX    }
  934. XX    return u;
  935. XX}
  936. XX#else
  937. XXstruct user *
  938. XXgetuser(p)
  939. XX    struct proc *p;
  940. XX{
  941. XX    struct pte *ptep, apte;
  942. XX    struct pte mypgtbl[NBPG/sizeof(struct pte)];
  943. XX    int upage;
  944. XX    char *up;
  945. XX    static struct user user;
  946. XX
  947. XX    /* easy way */
  948. XX    if ((p->p_flag & SLOAD) == 0) {
  949. XX        if (k_opt)
  950. XX            return (struct user *)NULL;
  951. XX        (void) lseek(swap, (ls_t)dtob(p->p_swaddr), 0);
  952. XX        if (read(swap, (char *)&user, sizeof(struct user))==0) {
  953. XX            (void) fprintf(stderr,
  954. XX                "%s: can't get swapped user page\n",
  955. XX                progname);
  956. XX            return (struct user *)NULL;
  957. XX        }
  958. XX        if (debug)
  959. XX            (void) printf("read swap\n");
  960. XX    } else {     /* boo */
  961. XX        ptep = &Usrptma[btokmx(p->p_p0br) + p->p_szpt - 1];
  962. XX
  963. XX        /* get the page table for the user page */
  964. XX        (void) lseek(kmem, (ls_t)ptep, 0);
  965. XX        if (read(kmem, (char *)&apte, sizeof(apte)) == 0) {
  966. XX            (void) fprintf(stderr,
  967. XX                "%s: can't get user page table\n",
  968. XX                progname);
  969. XX            return (struct user *)NULL;
  970. XX        }
  971. XX
  972. XX        /* now get this user's page table */
  973. XX        eseek(mem, (ls_t)ctob(apte.pg_pfnum) ,0, "page tbl");
  974. XX        if (read(mem, (char *)mypgtbl, sizeof(mypgtbl)) == 0) {
  975. XX            (void) fprintf(stderr,
  976. XX                "%s: can't get mypgtbl.\n", progname);
  977. XX            return (struct user *)NULL;
  978. XX        }
  979. XX        /* now collect various pages of u area */
  980. XX        for (upage = 0, up = (char *)&user; upage < sizeof(struct user)/NBPG; upage++) {
  981. XX            eseek(mem, (ls_t)ctob(mypgtbl[NPTEPG-UPAGES+upage].pg_pfnum), 0, "u page");
  982. XX            if (read(mem, up, NBPG) == 0) {
  983. XX                (void) fprintf(stderr,
  984. XX                    "%s: can't get page %d of user area.\n",
  985. XX                    progname, upage);
  986. XX                return(NULL);
  987. XX            }
  988. XX            up += NBPG;
  989. XX        }
  990. XX    }
  991. XX    return &user;
  992. XX}
  993. XX#endif
  994. XX
  995. XX#endif
  996. XX/*
  997. XX * read with error checking
  998. XX */
  999. XXvoid
  1000. XXeread(fd, p, size, s)
  1001. XX    int fd;
  1002. XX    char *p;
  1003. XX    int size;
  1004. XX    char *s;
  1005. XX{
  1006. XX    char buf[100];
  1007. XX    if (read(fd, p, size) != size) {
  1008. XX        if (!k_opt) {
  1009. XX            (void) fprintf(stderr, "%s: eread ", progname);
  1010. XX            perror("");
  1011. XX        }
  1012. XX        (void) sprintf(buf, "read error for %s\n", s);
  1013. XX        error(buf);
  1014. XX    }
  1015. XX}
  1016. XX
  1017. XX/*
  1018. XX * seek with error checking
  1019. XX */
  1020. XXvoid
  1021. XXeseek(fd, off, whence, s)
  1022. XX    int fd;
  1023. XX    ls_t off;
  1024. XX    int whence;
  1025. XX    char *s;
  1026. XX{
  1027. XX    ls_t ret;
  1028. XX    char buf[100];
  1029. XX
  1030. XX    if (( ret = lseek(fd, off, whence)) != off) {
  1031. XX        (void) sprintf(buf, "seek for %s failed, wanted %o, got %o.\n",
  1032. XX            s, off, ret);
  1033. XX        error(buf);
  1034. XX    }
  1035. XX}
  1036. XX
  1037. XX/*
  1038. XX * print mesg "s", don't exit if we are processing a core, 
  1039. XX * so that corrupt entries don't prevent further uncorrupted
  1040. XX * entries from showing up.
  1041. XX */
  1042. XXerror(s)
  1043. XX    char *s;
  1044. XX{
  1045. XX    if (s && !k_opt)
  1046. XX        (void) fprintf(stderr, "%s: %s", progname, s);
  1047. XX    if (!k_opt)
  1048. XX        exit(1);
  1049. XX}
  1050. XX
  1051. XX/*
  1052. XX * get some symbols form the kernel
  1053. XX */
  1054. XXgetsyms()
  1055. XX{
  1056. XX    register i;
  1057. XX
  1058. XX    if (k_opt) {
  1059. XX#ifdef    ultrix
  1060. XX        (void) nlist(namelist, nl);
  1061. XX#else    /* not ultrix */
  1062. XX        if (nlist(namelist, nl) == -1) {
  1063. XX            (void) fprintf(stderr,
  1064. XX                "%s: can't get name list from %s\n",
  1065. XX                progname, namelist);
  1066. XX            exit(1);
  1067. XX        }
  1068. XX#endif    /* ultrix */
  1069. XX    } else {
  1070. XX#ifdef    ultrix
  1071. XX        (void) nlist("/vmunix", nl);
  1072. XX#else    /* not ultrix */
  1073. XX#ifdef    DYNIX
  1074. XX        if (nlist("/dynix", nl) == -1)
  1075. XX#else    /* not DYNIX */
  1076. XX        if (nlist("/vmunix", nl) == -1)
  1077. XX#endif    /* DYNIX */
  1078. XX        {
  1079. XX            (void) fprintf(stderr,
  1080. XX                "%s: can't get name list from %s\n",
  1081. XX#ifdef    DYNIX
  1082. XX                progname, "/dynix");
  1083. XX#else    /* not DYNIX */
  1084. XX                progname, "/vmunix");
  1085. XX#endif    /* DYNIX */
  1086. XX            exit(1);
  1087. XX        }
  1088. XX#endif    /* ultrix */
  1089. XX    }
  1090. XX
  1091. XX    for (i = 0; i < (sizeof(nl)/sizeof(nl[0]))-1; i++)
  1092. XX        if (nl[i].n_value == 0) {
  1093. XX            (void) fprintf(stderr, "%s: can't nlist symbol %s\n",
  1094. XX                progname, nl[i].n_name);
  1095. XX            exit(1);
  1096. XX        }
  1097. XX
  1098. XX        eseek(kmem, (ls_t)(nl[X_PROC].n_value), 0, "procbase 1");
  1099. XX        eread(kmem, (char *)&procbase, sizeof(procbase), "procbase 1");
  1100. XX        eseek(kmem, (ls_t)(nl[X_NPROC].n_value), 0, "nproc");
  1101. XX        eread(kmem, (char *)&nproc, sizeof(nproc), "nproc");
  1102. XX
  1103. XX#ifndef    DYNIX
  1104. XX    Usrptma = (struct pte *)nl[X_USRPTMA].n_value;
  1105. XX    usrpt = (struct pte *)nl[X_USRPT].n_value;    /* used by <vmmac.h>*/
  1106. XX#endif
  1107. XX    return;
  1108. XX}
  1109. XX
  1110. XX/*
  1111. XX * read proc table entry "n" into buffer "p"
  1112. XX */
  1113. XXprocslot(n, p)
  1114. XX    int n;
  1115. XX    struct proc *p;
  1116. XX{
  1117. XX    if (k_opt)
  1118. XX        eseek(kmem, vtophys((ls_t)(procbase + (long)(n * sizeof(struct proc)))), 0, "proc");
  1119. XX    else
  1120. XX        eseek(kmem, (ls_t)(procbase + (long)(n * sizeof(struct proc))), 0, "proc");
  1121. XX    eread(kmem, (char *)p, sizeof(struct proc), "proc");
  1122. XX    return;
  1123. XX}
  1124. XX
  1125. XX/*
  1126. XX * When looking at kernel data space through /dev/mem or
  1127. XX * with a core file, do virtual memory mapping.
  1128. XX */
  1129. XXls_t
  1130. XXvtophys(vaddr)
  1131. XX    ls_t vaddr;
  1132. XX{
  1133. XX    u_int paddr;
  1134. XX    
  1135. XX#ifdef    i386
  1136. XX    if (vaddr < 8192)
  1137. XX        return vaddr;
  1138. XX#endif
  1139. XX    paddr = nl[X_SYSMAP].n_value;
  1140. XX    (void) lseek(kmem, (ls_t)paddr, 0);
  1141. XX    (void) read(kmem, (char *)&paddr, sizeof paddr);
  1142. XX    paddr = (int)((int *)paddr + (vaddr / NBPG));
  1143. XX    (void) lseek(kmem, (ls_t)paddr, 0);
  1144. XX    (void) read(kmem, (char *)&paddr, sizeof paddr);
  1145. XX#ifndef    i386
  1146. XX# define    PTBITS    0x1ff    /* 512 byte pages */
  1147. XX#else
  1148. XX# define    PTBITS    0xfff    /* 4096 byte pages */
  1149. XX#endif
  1150. XX
  1151. XX    return ((ls_t)(paddr & ~PTBITS) | (vaddr & PTBITS));
  1152. XX}
  1153. XX
  1154. XX/*
  1155. XX * get file pointer for socket
  1156. XX */
  1157. XXchar *
  1158. XXgetsockfp(cba, pfp)
  1159. XX    char *cba;
  1160. XX    struct file **pfp;
  1161. XX{
  1162. XX    register char *cp;
  1163. XX    struct file *socktofile();
  1164. XX    struct inpcb inpcb;
  1165. XX    static char nmbuf[128];
  1166. XX    struct socket sock;
  1167. XX    struct tcpcb tcpcb;
  1168. XX    long x;
  1169. XX
  1170. XX/*
  1171. XX * Convert PCB address from ASCII to hex.
  1172. XX */
  1173. XX    for (cp = cba, x = 0l; *cp; cp++) {
  1174. XX        x <<= 4;
  1175. XX        if (*cp >= '0' && *cp <= '9')
  1176. XX            x += *cp - '0';
  1177. XX        else if (*cp >= 'a' && *cp <= 'f')
  1178. XX            x += *cp - 'a' + 10;
  1179. XX        else if (*cp >= 'A' && *cp <= 'F')
  1180. XX            x += *cp - 'A' + 10;
  1181. XX        else {
  1182. XX            (void) fprintf(stderr,
  1183. XX                "%s: non-hex address, %s\n", progname, cba);
  1184. XX            return(NULL);
  1185. XX        }
  1186. XX    }
  1187. XX/*
  1188. XX * Read PCB and make sure it is in LISTEN or ESTABLISHED state.
  1189. XX */
  1190. XX    eseek(kmem, (ls_t)x, 0, "tcpcb");
  1191. XX    eread(kmem, (char *)&tcpcb, sizeof(tcpcb), "tcpcb");
  1192. XX    if (tcpcb.t_state < TCPS_LISTEN || tcpcb.t_state > TCPS_ESTABLISHED) {
  1193. XX        (void) fprintf(stderr,
  1194. XX            "%s: PCB %x not in LISTEN to ESTABLISHED state\n",
  1195. XX            progname, x);
  1196. XX        return(NULL);
  1197. XX    }
  1198. XX    if (tcpcb.t_inpcb == (struct inpcb *)0) {
  1199. XX        (void) fprintf(stderr,
  1200. XX            "%s: PCB %x has no INPCB\n",
  1201. XX            progname, x);
  1202. XX        return(NULL);
  1203. XX    }
  1204. XX/*
  1205. XX * Read INPCB for PCB and make sure it points back to the PCB.
  1206. XX */
  1207. XX    eseek(kmem, (ls_t)tcpcb.t_inpcb, 0, "inpcb");
  1208. XX    eread(kmem, (char *)&inpcb, sizeof(inpcb), "inpcb");
  1209. XX    if ((caddr_t)x != inpcb.inp_ppcb) {
  1210. XX        (void) fprintf(stderr,
  1211. XX            "%s: INPCB for PCB %x not linked to it\n",
  1212. XX            progname, x);
  1213. XX        return(NULL);
  1214. XX    }
  1215. XX/*
  1216. XX * Read the socket and make sure it points back to the INPCB.
  1217. XX */
  1218. XX    eseek(kmem, (ls_t)inpcb.inp_socket, 0, "socket");
  1219. XX    eread(kmem, (char *)&sock, sizeof(sock), "socket");
  1220. XX    if (sock.so_pcb != (caddr_t)tcpcb.t_inpcb) {
  1221. XX        (void) fprintf(stderr,
  1222. XX            "%s: socket not linked to INPCB for PCB %x\n",
  1223. XX            progname, x);
  1224. XX        return(NULL);
  1225. XX    }
  1226. XX/*
  1227. XX * Find the file structure that is linked to the socket.
  1228. XX */
  1229. XX    if ((*pfp = socktofile((caddr_t)inpcb.inp_socket)) == NULL) {
  1230. XX        (void) fprintf(stderr,
  1231. XX            "%s: no file structure for socket of PCB %x\n",
  1232. XX            progname, x);
  1233. XX        return(NULL);
  1234. XX    }
  1235. XX/*
  1236. XX * Construct a pseudo file name and return it.
  1237. XX */
  1238. XX    (void) sprintf(nmbuf,
  1239. XX        "file %lx of socket %lx of INPCB %lx of PCB %lx",
  1240. XX        (long)*pfp, (long)inpcb.inp_socket, (long)tcpcb.t_inpcb, x);
  1241. XX    return(nmbuf);
  1242. XX}
  1243. XX
  1244. XX/*
  1245. XX * Convert a socket address to a file address.
  1246. XX */
  1247. XXstruct file *
  1248. XXsocktofile(s)
  1249. XX    caddr_t s;
  1250. XX{
  1251. XX    register struct file *afile;
  1252. XX    char *calloc();
  1253. XX    register struct file *fp;
  1254. XX    static struct file *ftp;
  1255. XX    static int nfile = -1;
  1256. XX    static struct file *xfile = NULL;
  1257. XX
  1258. XX/*
  1259. XX * Read the size of file table, allocate space
  1260. XX * for it, and read the file table pointer (once).
  1261. XX */
  1262. XX    if (nfile < 0) {
  1263. XX        eseek(kmem, (ls_t)(nl[SNFILE].n_value), 0, "_nfile");
  1264. XX        eread(kmem, (char *)&nfile, sizeof(nfile), "_nfile");
  1265. XX        xfile = (struct file *) calloc((unsigned)nfile, sizeof (struct file));
  1266. XX        eseek(kmem, (ls_t)(nl[SFIL].n_value), 0, "_file");
  1267. XX        eread(kmem, (char *)&ftp, sizeof(ftp), "_file");
  1268. XX    }
  1269. XX/*
  1270. XX * Read the file table and search for an in-use
  1271. XX * socket file with a matching data address.
  1272. XX */
  1273. XX    eseek(kmem, (ls_t)ftp, 0, "_file");
  1274. XX    eread(kmem, (char *)xfile, nfile * sizeof(struct file), "_file");
  1275. XX    for (fp = xfile, afile = ftp; fp < &xfile[nfile]; fp++, afile++) {
  1276. XX        if (fp->f_count && fp->f_type == DTYPE_SOCKET
  1277. XX        &&  s == fp->f_data)
  1278. XX            return(afile);
  1279. XX    }
  1280. XX    return(NULL);
  1281. XX}
  1282. SHAR_EOF
  1283. if test 24522 -ne "`wc -c ofiles.c`"
  1284. then
  1285. echo shar: error transmitting ofiles.c '(should have been 24522 characters)'
  1286. fi
  1287. echo shar: extracting ofiles.8l '(5223 characters)'
  1288. sed 's/^XX//' << \SHAR_EOF > ofiles.8l
  1289. XX.TH OFILES 8L LOCAL
  1290. XX.SH NAME
  1291. XXofiles \- show owner of open file or network connection
  1292. XX.SH SYNOPSIS
  1293. XX.B ofiles
  1294. XX[
  1295. XX.B \-d
  1296. XX] [
  1297. XX.B \-k
  1298. XX.I nlist
  1299. XX.I core
  1300. XX] [
  1301. XX.B \-n
  1302. XX] [
  1303. XX.B \-p
  1304. XX]
  1305. XX.I names
  1306. XX.SH DESCRIPTION
  1307. XX.I Ofiles
  1308. XXdisplays the owner, process identification (PID), type, command and
  1309. XXthe number of the inode associated with an open instance of a file
  1310. XXor a network connection.
  1311. XX.PP
  1312. XXAn open file may be a regular file, a file system or a directory;
  1313. XXit is specified by its path name.
  1314. XXWhen the path name refers to a file system,
  1315. XX.I ofiles
  1316. XXwill display the owners of all open instances of files in the system.
  1317. XX.PP
  1318. XXAn open network connection is specified by the kernel address of its
  1319. XXProtocol Control Block (PCB), as displayed by
  1320. XX.IR netstat (8),
  1321. XXwhen its
  1322. XX.B \-A
  1323. XXoption is specified.
  1324. XX.SH OPTIONS
  1325. XX.I Ofiles
  1326. XXdisplays information about its usage if no options are specified.
  1327. XX.TP \w'-kXnlistXcore'u+4
  1328. XX.BI \-d
  1329. XXThis option selects verbose, debugging output.
  1330. XX.TP
  1331. XX.BI \-k \ nlist\ core
  1332. XXThis option may be used only on DYNIX hosts.
  1333. XXIt sets optional name list and core file paths.
  1334. XX.IP
  1335. XX.I Nlist
  1336. XXis the path to the file from which
  1337. XX.I ofiles
  1338. XXshould obtain the addresses of kernel symbols,
  1339. XXinstead of from
  1340. XX.IR /dynix .
  1341. XX.IP
  1342. XX.I Core
  1343. XXis the path to the file from which
  1344. XX.I ofiles
  1345. XXshould obtain the value of kernel symbols,
  1346. XXinstead of from
  1347. XX.IR /dev/mem .
  1348. XX.IP
  1349. XXThis option is useful for debugging system crash dumps.
  1350. XX.TP
  1351. XX.B \-n
  1352. XXThis option specifies that the
  1353. XX.I name
  1354. XXarguments identify network connections by their hexadecimal, Protocol
  1355. XXControl Block (PCB) addresses.
  1356. XXPCB addresses can be obtained via the
  1357. XX.B \-A
  1358. XXoption of
  1359. XX.IR netstat (1).
  1360. XX.IP
  1361. XXThis option makes it possible to determine the local processes that
  1362. XXare using network connections in the LISTEN through ESTABLISHED states.
  1363. XX.TP
  1364. XX.B \-p 
  1365. XXThis option specifies that
  1366. XX.I ofiles
  1367. XXshould print process identifiers only \- e. g., so that the output may
  1368. XXbe piped to
  1369. XX.IR kill (1).
  1370. XX.TP
  1371. XX.I names
  1372. XXThese are path names of files, directories and file systems;
  1373. XXor, if the
  1374. XX.B \-n
  1375. XXoption has been specified, network connections, identified by their
  1376. XXhexadecimal Protocol Control Block (PCB) addresses.
  1377. XX.SH OUTPUT
  1378. XX.I Ofiles
  1379. XXdisplays for each
  1380. XX.IR name :
  1381. XX.TP \w'name/linkages'u+4
  1382. XX.I name/linkages
  1383. XXfor file paths, an interpretation of the type of name \- file, directory
  1384. XXor file system;
  1385. XXfor network connections, the kernel address linkages, starting with the file
  1386. XXstructure and proceeding through the socket structure and the Internet
  1387. XXProtocol Control Block (INPCB) structure to the PCB
  1388. XX.TP
  1389. XX.B USER
  1390. XXthe login name of the user of the process that has
  1391. XX.I name
  1392. XXopen
  1393. XX.TP
  1394. XX.B PID
  1395. XXthe identifier of the process that has
  1396. XX.I name
  1397. XXopen
  1398. XX.TP
  1399. XX.B TYPE
  1400. XXa file type explanation:
  1401. XX.RS
  1402. XX.TP \w'file'u+4
  1403. XX.B cwd 
  1404. XXif
  1405. XX.I name
  1406. XXis the current working directory of the process
  1407. XX.TP
  1408. XX.B file
  1409. XXif
  1410. XX.I name
  1411. XXis being used as a regular file by the process, optionally followed by:
  1412. XX.RS
  1413. XX.TP
  1414. XX.B /s
  1415. XXif the process has a shared lock on the file
  1416. XX.TP
  1417. XX.B /x
  1418. XXif the process has an exclusive lock on the file
  1419. XX.RE
  1420. XX.TP
  1421. XX.B rdir
  1422. XXif 
  1423. XX.I name
  1424. XXis the root directory of the process
  1425. XX.TP
  1426. XX.B sock
  1427. XXif
  1428. XX.I name
  1429. XXis a socket
  1430. XX.RE
  1431. XX.TP
  1432. XX.B FD
  1433. XXthe file descriptor number, local to the process
  1434. XX.TP
  1435. XX.B CMD
  1436. XXthe user command that opened
  1437. XX.I name
  1438. XX.TP
  1439. XX.B INODE
  1440. XXthe inode number of the file
  1441. XX.SH EXAMPLES
  1442. XXThis example shows the use of
  1443. XX.I ofiles
  1444. XXto discover the owner of the open, regular file,
  1445. XX.IR /usr/spool/lpd/lock .
  1446. XX.PP
  1447. XX.RS
  1448. XX.nf
  1449. XX% ofiles /usr/spool/lpd/lock
  1450. XX.br
  1451. XX/usr/spool/lpd/lock    
  1452. XX.br
  1453. XXUSER    PID    TYPE      FD    CMD    INODE
  1454. XX.br
  1455. XXroot    110    file/x     3    lpd    26683
  1456. XX.fi
  1457. XX.RE
  1458. XX.PP
  1459. XXThis example shows the use of
  1460. XX.IR netstat (1),
  1461. XX.IR grep (1)
  1462. XXand
  1463. XX.I ofiles
  1464. XXto identify the local endpoint of the ``smtp'' network connection.
  1465. XXThe first column of output from
  1466. XX.I netstat
  1467. XXis the PCB address; it is used as the
  1468. XX.I name
  1469. XXargument to
  1470. XX.IR ofiles ,
  1471. XXalong with the
  1472. XX.B \-n
  1473. XXoption.
  1474. XX.PP
  1475. XX.RS
  1476. XX.nf
  1477. XX% netstat -aA | grep smtp
  1478. XX.br
  1479. XX80f6770c    tcp    0    0    *.smtp    *.*    LISTEN
  1480. XX.br
  1481. XX% ofiles -n 80f6770c
  1482. XX.br
  1483. XXfile 80102b64 of socket 80f6758c of INPCB 80f6780c of PCB 80f6770c    
  1484. XX.br
  1485. XXUSER    PID    TYPE    FD    CMD
  1486. XX.br
  1487. XXroot    105    sock     5    sendmail 
  1488. XX.fi
  1489. XX.RE
  1490. XX.SH DIAGNOSTICS
  1491. XXErrors are identified with messages on the standard error file.
  1492. XX.PP
  1493. XX.I Ofiles
  1494. XXreturns a one (1) if any error was detected, including the failure to
  1495. XXlocate any
  1496. XX.IR names .
  1497. XXIt returns a zero (0) if no errors were detected and if it was able to
  1498. XXdisplay owner information about all the specified
  1499. XX.IR names .
  1500. XX.SH BUGS
  1501. XX.I Ofiles
  1502. XXcan't identify SunOS 4.0 stream files, so it doesn't follow their file
  1503. XXstructure pointers correctly when reading their inodes.
  1504. XXThat results in the display of erroneous inode numbers for stream files.
  1505. XX.PP
  1506. XXThe
  1507. XX.B \-n
  1508. XXoption limits its search to network connections in the LISTEN through
  1509. XXESTABLISHED states.
  1510. XX.PP
  1511. XXSince
  1512. XX.I ofiles
  1513. XXreads kernel memory in its search for open files and network connections,
  1514. XXrapid changes in kernel memory may produce unsatisfactory results.
  1515. XX.SH AUTHORS
  1516. XXC. Spencer is the original author.
  1517. XXMichael Ditto, Tom Dunigan, Alexander Dupuy, Gary Nebbett and Richard Tobin
  1518. XXcontributed.
  1519. XX.PP
  1520. XXMichael Spitzer, Ray Moody, and Vik Lall of the Purdue University Computing
  1521. XXCenter converted the program to a variety of UNIX environments.
  1522. XX.PP
  1523. XXVic Abell of the Purdue University Computing Center added the
  1524. XX.B \-n
  1525. XXoption.
  1526. XX.SH SEE ALSO
  1527. XXinode(5),
  1528. XXmount(1),
  1529. XXkill(1),
  1530. XXtcp(4).
  1531. SHAR_EOF
  1532. if test 5223 -ne "`wc -c ofiles.8l`"
  1533. then
  1534. echo shar: error transmitting ofiles.8l '(should have been 5223 characters)'
  1535. fi
  1536. #    End of shell archive
  1537. exit 0
  1538.  
  1539. -- 
  1540. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  1541.  
  1542.  
  1543.